/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jtwitterclient;

import java.awt.event.*;
import java.awt.Insets;
import java.awt.BorderLayout;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import java.util.*;
import winterwell.jtwitter.Twitter;
import winterwell.jtwitter.Twitter.Status;
import winterwell.jtwitter.Twitter.User;

/**
 *
 * @author Administrator
 */
public class Timeline extends JFrame {

    Twitter api;
    JButton refresh = new JButton(new ImageIcon("img/refresh.PNG"));
    JButton home = new JButton(new ImageIcon("img/home.PNG"));
    JButton reply = new JButton(new ImageIcon("img/reply.PNG"));
    JButton favorites = new JButton(new ImageIcon("img/favorites.PNG"));
    JButton following = new JButton(new ImageIcon("img/following.PNG"));
    JButton followers = new JButton(new ImageIcon("img/followers.PNG"));
    JButton me = new JButton();
    JScrollPane pCenter = new JScrollPane();
    String type = "home";//home reply favorites me another_user following followers
    JButton bts[];
    String others = null;
    JTextArea input = new JTextArea();
    ImageButton post = new ImageButton("img/post.PNG", "post");
    ImageButton next = new ImageButton("img/next.PNG", "next");
    List<Status> timeLineView = null;
    List<Long> peopleList = null;
    int page = 0;
    int start;
    int end;

    public Timeline(Twitter _api) {
        this.api = _api;
        try {
            me = new JButton(new ImageIcon(api.getUser(api.getScreenName()).getProfileImageUrl().toURL()));
        } catch (MalformedURLException ex) {
            Logger.getLogger(Timeline.class.getName()).log(Level.SEVERE, null, ex);
        }
        next.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                if (page * 20 >= peopleList.size()) {
                    JOptionPane.showConfirmDialog(null, "now more content...", "error", JOptionPane.CLOSED_OPTION, JOptionPane.WARNING_MESSAGE);
                } else {
                    start = page * 20;
                    end = peopleList.size() >= start + 20 ? start + 20 : peopleList.size();//one page max :20 items

                    updateCenter();


                }
            }
        });
        me.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                page = 0;
                type = "me";
                updateCenter();
            }
        });
        refresh.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                updateCenter();
            }
        });
        home.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                type = "home";
                updateCenter();
            }
        });
        reply.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                page = 0;
                type = "reply";
                updateCenter();
            }
        });
        favorites.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                page = 0;
                type = "favorites";
                updateCenter();
            }
        });
        following.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                page = 0;
                type = "following";
                peopleList = api.getFriendIDs();
                start = 0;
                end = peopleList.size() >= 20 ? 20 : peopleList.size();
                System.out.println(type);
                updateCenter();
            }
        });
        followers.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                page = 0;
                type = "followers";
                peopleList = api.getFollowerIDs();
                start = 0;
                end = peopleList.size() >= 20 ? 20 : peopleList.size();
                System.out.println(type);
                updateCenter();
            }
        });
        JToolBar toolbar = new JToolBar();
        toolbar.add(refresh);
        toolbar.add(home);
        toolbar.add(reply);
        toolbar.add(me);
        toolbar.add(favorites);
        toolbar.add(following);
        toolbar.add(followers);
        toolbar.setFloatable(false);

        bts = new JButton[20];//默认显示20条记录
        for (int i = 0; i < 20; i++) {
            bts[i] = new JButton();
            bts[i].addActionListener(new ActionListener() {

                public void actionPerformed(ActionEvent e) {
                    type = "another_user";
                    others = e.getActionCommand();
                    System.out.println(e.getActionCommand());
                    updateCenter();
                }
            });
        }

        setLayout(new BorderLayout());
        add(toolbar, BorderLayout.NORTH);

        updateCenter();
        add(pCenter, BorderLayout.CENTER);        

        input.setColumns(50);
        Box boxSouth = Box.createHorizontalBox();
        boxSouth.add(input);
        boxSouth.add(post);
        post.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                if (input.getText().length() > 140) {
                    JOptionPane.showConfirmDialog(null, "the tweet is too long...", "error", JOptionPane.CLOSED_OPTION, JOptionPane.WARNING_MESSAGE);
                } else if (input.getText().length() == 0) {
                    JOptionPane.showConfirmDialog(null, "the tweet cannot be empty...", "error", JOptionPane.CLOSED_OPTION, JOptionPane.WARNING_MESSAGE);
                } else {
                    postTweete();
                }
            }
        });

        add(boxSouth, BorderLayout.SOUTH);

        setTitle("Timeline");
        setSize(500, 600);
        setLocationRelativeTo(null);
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void postTweete() {
        new postTweeteThread(this).start();
    }

    public void updateStatus() {
        api.setStatus(input.getText());
        JOptionPane.showConfirmDialog(this, "status successfully updated!", "info", JOptionPane.CLOSED_OPTION, JOptionPane.INFORMATION_MESSAGE);
        input.setText("");
    }

    private void print(Object ob) {
        System.out.println(ob);
    }

    public void updateCenter() {
        new updateThread(this).start();
    }

    public static void main(String[] args) {
    }
}

class postTweeteThread extends Thread {

    Timeline timeline;

    postTweeteThread(Timeline timeline) {
        this.timeline = timeline;
    }

    @Override
    public void run() {
        timeline.updateStatus();
    }
}

class updateThread extends Thread {

    Timeline timeline;
    Box box = Box.createVerticalBox();
    Box item;
    ImageIcon icon;
    JTextArea content;
    Waiting dlg;
    int type;
    Status status;
    User user;
    Runnable sectionOne = null;
    int i;

    updateThread(Timeline timeline) {
        this.timeline = timeline;
        sectionOne = new Runnable() {

            public void run() {
                dlg = new Waiting();
                dlg.setLocationRelativeTo(null);
            }
        };
    }

    @Override
    public void run() {
        try {
            System.out.println("-------start------------");
            /* dlg = new Waiting();
            dlg.setLocationRelativeTo(null);*/
            SwingUtilities.invokeAndWait(sectionOne);



            if (timeline.type.equals("home")) {
                timeline.timeLineView = timeline.api.getHomeTimeline();//Status
                System.out.println("in home len:" + timeline.timeLineView.size());
                type = 0;
            } else if (timeline.type.equals("reply")) {
                timeline.timeLineView = timeline.api.getReplies();//Status
                System.out.println("in reply len:" + timeline.timeLineView.size());
                type = 0;
            } else if (timeline.type.equals("favorites")) {
                timeline.timeLineView = timeline.api.getFavorites();//Status
                System.out.println("in favorites len:" + timeline.timeLineView.size());
                type = 0;
            } else if (timeline.type.equals("me")) {
                timeline.timeLineView = timeline.api.getUserTimeline();//Status
                System.out.println("in me len:" + timeline.timeLineView.size());
                type = 0;
            } else if (timeline.type.equals("another_user")) {
                timeline.timeLineView = timeline.api.getUserTimeline(timeline.others);//Status
                System.out.println("in another_user len:" + timeline.timeLineView.size());
                type = 0;
            } else if (timeline.type.equals("following")) {
                // timeline.peopleList = timeline.api.getFriendIDs();//Long
                type = 1;
            } else if (timeline.type.equals("followers")) {
                //   timeline.peopleList = timeline.api.getFollowerIDs();//Long
                type = 1;
            }

            if (type == 0) {
                SwingUtilities.invokeAndWait(new Runnable() {

                    public void run() {
                        dlg.adoptDeterminate(timeline.timeLineView.size());

                    }
                });
                setTimeLine();

            } else {
                System.out.println("TEST");
                SwingUtilities.invokeAndWait(new Runnable() {

                    public void run() {
                        //dlg.adoptDeterminate(timeline.peopleList.size() >= 20 ? 20 : timeline.peopleList.size());
                        dlg.adoptDeterminate(timeline.end - timeline.start);
                        System.out.print("adoptDeterminate:------->");
                        System.out.println(timeline.end - timeline.start);
                    }
                });
                setPeopleList();

            }


            SwingUtilities.invokeLater(new Runnable() {//这个排在最后 不用考虑顺序的先后了 所以不用AndWait而用Later

                public void run() {
                    dlg.finishDeterminate();
                    timeline.pCenter.setViewportView(box);
                    timeline.pCenter.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
                }
            });
            System.out.println("-------end------------");
            System.out.println();
        } catch (Exception e) {
            System.out.println("" + e);
            dlg.dispose();
        }
    }

    public void setTimeLine() {
        for (i = 0; i < timeline.timeLineView.size(); i++) {
            status = timeline.timeLineView.get(i);
            try {
                SwingUtilities.invokeAndWait(new Runnable() {

                    public void run() {
                        dlg.setValue(i);
                        content = new JTextArea(status.getText());
                        content.setLineWrap(true);
                        content.setWrapStyleWord(true);
                        content.setColumns(30);
                        content.setEditable(false);
                        // content.setBackground(Color.cyan);
                        item = Box.createHorizontalBox();
                        //icon = new ImageIcon("img/id_img.jpg");
                    }
                });
            } catch (InterruptedException ex) {
                Logger.getLogger(updateThread.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InvocationTargetException ex) {
                Logger.getLogger(updateThread.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println("status id:" + status.getId());
            try {//time consuming
                icon = new ImageIcon(status.getUser().getProfileImageUrl().toURL());
            } catch (MalformedURLException ex) {
                Logger.getLogger(Timeline.class.getName()).log(Level.SEVERE, null, ex);
            }

            System.out.println("***********************************" + i + "*******************************");
            try {
                SwingUtilities.invokeAndWait(new Runnable() {

                    public void run() {
                        timeline.bts[i].setIcon(icon);
                        timeline.bts[i].setSize(icon.getIconWidth(), icon.getIconHeight());
                        timeline.bts[i].setMargin(new Insets(0, 0, 0, 0)); //设置按钮边框和标签之间的空白
                        timeline.bts[i].setIconTextGap(0); //设置文本间隙
                        timeline.bts[i].setBorderPainted(false); //设置是否允许绘制边框
                        timeline.bts[i].setActionCommand(status.getUser().getScreenName());
                        item.add(timeline.bts[i]);
                        item.add(Box.createHorizontalStrut(5));
                        item.add(content);
                        box.add(item);
                        box.add(Box.createVerticalStrut(5));
                        if (i == timeline.timeLineView.size() - 1) {
                            Box last = Box.createHorizontalBox();
                            last.add(Box.createHorizontalStrut(50));
                            last.add(timeline.next);
                            box.add(last);
                            box.add(Box.createVerticalStrut(5));
                        }
                    }
                });
            } catch (InterruptedException ex) {
                Logger.getLogger(updateThread.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InvocationTargetException ex) {
                Logger.getLogger(updateThread.class.getName()).log(Level.SEVERE, null, ex);
            }


        }
    }

    public void setPeopleList() {
        /*   int lastOfPage;
        if (timeline.peopleList.size() >= 20) {
        lastOfPage = 20;
        } else {
        lastOfPage = timeline.peopleList.size();
        }*/
        // for (i = 0; i < lastOfPage; i++) {
        for (i = timeline.start; i < timeline.end; i++) {
            user = timeline.api.getUser(timeline.peopleList.get(i));
            try {
                SwingUtilities.invokeAndWait(new Runnable() {

                    public void run() {
                        dlg.setValue(i-timeline.page*20);//针对后面几页的处理 起始值必须调成零 否则next没有进度条的效果
                        content = new JTextArea(user.getDescription() + " \n" + user.getWebsite());
                        content.setLineWrap(true);
                        content.setWrapStyleWord(true);
                        content.setColumns(30);
                        content.setEditable(false);
                        // content.setBackground(Color.cyan);
                        item = Box.createHorizontalBox();
                        //icon = new ImageIcon("img/id_img.jpg");
                    }
                });
            } catch (InterruptedException ex) {
                Logger.getLogger(updateThread.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InvocationTargetException ex) {
                Logger.getLogger(updateThread.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println("user id:" + user.getName());

            try {// time consuming
                icon = new ImageIcon(user.getProfileImageUrl().toURL());
            } catch (MalformedURLException ex) {
                Logger.getLogger(Timeline.class.getName()).log(Level.SEVERE, null, ex);
            }
            try {
                SwingUtilities.invokeAndWait(new Runnable() {

                    public void run() {
                        int seq = timeline.page > 0 ? (i % (timeline.page * 20)) : i;
                        timeline.bts[seq].setIcon(icon);
                        timeline.bts[seq].setSize(icon.getIconWidth(), icon.getIconHeight());
                        timeline.bts[seq].setMargin(new Insets(0, 0, 0, 0)); //设置按钮边框和标签之间的空白
                        timeline.bts[seq].setIconTextGap(0); //设置文本间隙
                        timeline.bts[seq].setBorderPainted(false); //设置是否允许绘制边框
                        timeline.bts[seq].setActionCommand(user.getScreenName());
                        item.add(timeline.bts[seq]);
                        item.add(Box.createHorizontalStrut(5));
                        item.add(content);
                        box.add(item);
                        box.add(Box.createVerticalStrut(5));
                        if (i == timeline.end - 1) {
                            timeline.page++;
                            Box last = Box.createHorizontalBox();
                            last.add(Box.createHorizontalStrut(50));
                            last.add(timeline.next);
                            box.add(last);
                            box.add(Box.createVerticalStrut(5));
                        }
                    }
                });
            } catch (InterruptedException ex) {
                Logger.getLogger(updateThread.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InvocationTargetException ex) {
                Logger.getLogger(updateThread.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
    }
}
